﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Ascent.QiPei.Module.BusinessObjects.Base;
using Ascent.QiPei.Module.BusinessObjects.Common;
using Ascent.QiPei.Module.BusinessObjects.Enums;
using Ascent.QiPei.Module.BusinessObjects.Sales;
using Ascent.QiPei.Module.BusinessObjects.Systems;
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.Xpo;
using System.Linq;
using DevExpress.XtraEditors;
using Ascent.QiPei.Module.BusinessObjects.Purchase;

namespace Ascent.QiPei.Module.Win.Sales
{
    public partial class SaleOrderForm : DevExpress.XtraEditors.XtraForm
    {
        private ICollection<Product> productSearchResultCollection;
        private IList<Product> lstProduct;
        private ICollection<SaleOrderItems> saleOrderItemsCollection;
        public SaleOrder currSaleOrder;
        public string queryWhereString = string.Empty;
        IObjectSpace objectSpace;
        public SaleOrderForm()
        {
            InitializeComponent();

        }
        Session session1 = new Session() { ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ToString() };
        public SaleOrderForm(IObjectSpace os)
        {
            InitializeComponent();
            //this.xpCollection1.Session = session1;
            objectSpace = os;
        }

        private void LoadDropDownSource()
        {
            IList<Customer> lstCustomer = objectSpace.GetObjects<Customer>();
            IList<Employee> lstEmployee = objectSpace.GetObjects<Employee>();
            this.editCustomerName.Properties.DataSource = lstCustomer;
            this.editEmployee.Properties.DataSource = lstEmployee;

            //GroupOperator groupOperator = new GroupOperator();
            //groupOperator.Operands.Add();

            //CriteriaOperator filter = new BinaryOperator( new AggregateOperand("OrderProducts", Aggregate.Count, CriteriaOperator.And(new BinaryOperator("IsDeleted", false), groupOperator)), new OperandValue(0), BinaryOperatorType.Greater);
            
            //CriteriaOperator filter = new AggregateOperand("OrderProducts", Aggregate.Exists, CriteriaOperator.And(new NotOperator(new OperandProperty("IsDeleted")), groupOperator));
            //IList<Product> lstProduct = objectSpace.GetObjects<CriteriaOperator.p
            foreach (var item in lstCustomer)
            {
                this.editProductCode.Properties.Items.Add(item.ShortName);
            }
        }

        private void SaleOrderForm_Load(object sender, EventArgs e)
        {
            saleOrderItemsCollection = new List<SaleOrderItems>();
            unitOfWork.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
            //unitOfWork.conn
            gvSearchResult.DoubleClick += gvSearchResult_DoubleClick;
            gvSearchResult.KeyDown += gvSearchResult_KeyDown;
            gvSearchResult.Click += gvSearchResult_Click;
            // Make the grid read-only 
            gvSearchResult.OptionsBehavior.Editable = false;
            // Prevent focused cell from being highlighted 
            gvSearchResult.OptionsSelection.EnableAppearanceFocusedCell = false;
            // Draw dotted focus rectangle around entire row 
            gvSearchResult.FocusRectStyle = DevExpress.XtraGrid.Views.Grid.DrawFocusRectStyle.RowFocus;

            gvSaleOrder.CellValueChanged += gvSaleOrder_CellValueChanged;

            //新的销售单
            if (currSaleOrder == null)
            {
                currSaleOrder = objectSpace.CreateObject<SaleOrder>();
                CodeUtil codeUtil = new CodeUtil(unitOfWork);
                currSaleOrder.SOCode = codeUtil.GenerateCode(BusinessObjects.Enums.CodeNameType.销售单);
                currSaleOrder.CreateDate = DateTime.Now;
                currSaleOrder.SoStatus = OrderStatusType.已开单;
                this.txtSOCode.Text = currSaleOrder.SOCode;
                this.dtDeliveryDate.DateTime = DateTime.Now;
                objectSpace.CommitChanges();
                this.LoadDropDownSource();
            }
            else //编辑销售单
            {
                this.LoadSaleOrder(currSaleOrder);
            }
        }

        void gvSaleOrder_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
        {
            SaleOrderItems currItem = (SaleOrderItems)gvSaleOrder.GetRow(e.RowHandle);
            currItem.Amount = currItem.Quantity * currItem.UnitPrice - currItem.DiscountAmount;
            this.SaleOrderGridControl.RefreshDataSource();
        }

        /// <summary>
        /// 加载一个已有的销售单
        /// </summary>
        private void LoadSaleOrder(SaleOrder so)
        {
            this.txtSOCode.Text = so.SOCode;
            //this.txtCustomerName.Text = so.Customer.ShortName;
            this.editCustomerName.EditValue = so.Customer.ShortName;
            this.dtDeliveryDate.DateTime = so.DeliveryDate;

            this.SaleOrderGridControl.DataSource = currSaleOrder.SaleOrderItems;
            this.SaleOrderGridControl.RefreshDataSource();
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            SearchStock();
        }

        private void SearchStock()
        {
            LoadDataMemberOrderItem[] productLoadOrder = new LoadDataMemberOrderItem[] 
            {
                new LoadDataMemberOrderItem(0, "ProductCode"),
                new LoadDataMemberOrderItem(1, "ProductName"),
                new LoadDataMemberOrderItem(2, "ProductSpecification"),
                new LoadDataMemberOrderItem(3, "AvailableQuantity")
            };

            //string queryString = "Select ProductCode,ProductName,ProductSpecification,AvailableQuantity,RetailPrice from Product where 1=1";
            CriteriaOperator op = CriteriaOperator.Parse("1=1", string.Empty);
            if (!string.IsNullOrEmpty(this.editProductCode.Text))
            {
                op = GroupOperator.Combine(GroupOperatorType.And, op, new BinaryOperator("ProductCode", "%" + this.editProductCode.Text + "%", BinaryOperatorType.Like));
            }
            if (!string.IsNullOrEmpty(this.editProductName.Text))
            {
                op = GroupOperator.Combine(GroupOperatorType.And, op, new BinaryOperator("ProductName", "%" + this.editProductName.Text + "%", BinaryOperatorType.Like));
            }
            if (!string.IsNullOrEmpty(this.editProductSpecification.Text))
            {
                op = GroupOperator.Combine(GroupOperatorType.And, op, new BinaryOperator("ProductSpecification", "%" + this.editProductSpecification.Text + "%", BinaryOperatorType.Like));
            }
            if (!string.IsNullOrEmpty(this.editProducingArea.Text))
            {
                op = GroupOperator.Combine(GroupOperatorType.And, op, new BinaryOperator("ProducingArea", "%" + this.editProducingArea.Text + "%", BinaryOperatorType.Like));
            }
            lstProduct = objectSpace.GetObjects<Product>(op);
            this.SearchResultGridControl.DataSource = lstProduct;
        }

        private void ShowConfirmAddWin()
        {
            int i = gvSearchResult.GetDataSourceRowIndex(gvSearchResult.FocusedRowHandle);
            Product currProduct = (Product)gvSearchResult.GetRow(i);
            currSaleOrder.Customer = objectSpace.FindObject<Customer>(CriteriaOperator.Parse("CustomerCode = ?", this.editCustomerName.EditValue));
            AddConfirmForm addForm = new AddConfirmForm(1, GetCustomerPrice(currProduct));
            if (DialogResult.OK == addForm.ShowDialog(this))
            {
                SaleOrderItems orderItem = objectSpace.CreateObject<SaleOrderItems>();
                orderItem.SaleOrder = currSaleOrder;
                orderItem.Product = currProduct;
                orderItem.Quantity = addForm.quantity;
                orderItem.UnitPrice = addForm.price;
                orderItem.Amount = orderItem.Quantity * orderItem.UnitPrice - orderItem.DiscountAmount;
                saleOrderItemsCollection.Add(orderItem);
                objectSpace.CommitChanges();
                this.SaleOrderGridControl.DataSource = saleOrderItemsCollection;
                this.SaleOrderGridControl.RefreshDataSource();
            }
        }

        /// <summary>
        /// 获取客户的设置价格
        /// </summary>
        /// <param name="product"></param>
        /// <returns></returns>
        private float GetCustomerPrice(Product product)
        {
            float customerPrice = 0;
            Option option = objectSpace.FindObject<Option>(CriteriaOperator.Parse("DefaultLastPrice == true"));

            if (option != null && currSaleOrder.Customer != null)
            {
                string queryString = "Select Top 1 A.UnitPrice From [SaleOrderItems] A Left Join [SaleOrder] B On A.SaleOrder=B.Oid Where " +
                    "A.Product='{0}' And A.SaleOrder=B.Oid And B.Customer='{1}' And (B.SoStatus={2} Or B.SoStatus={3} Or B.SoStatus={4}) Order by B.CreateDate Desc";
                queryString = string.Format(queryString, product.Oid, currSaleOrder.Customer.Oid, (int)OrderStatusType.已确认, (int)OrderStatusType.已审核, (int)OrderStatusType.已付款);
                Object objUnitPrice = unitOfWork.ExecuteScalar(queryString);
                if (objUnitPrice != null)
                    customerPrice = (float)(double)objUnitPrice;

                if (customerPrice > 0)
                    return customerPrice;
            }
            SalesType customerSalesType = SalesType.零售;
            if (currSaleOrder.Customer != null)
                customerSalesType = currSaleOrder.Customer.CustomerType.PriceType;

            switch (customerSalesType)
            {
                case SalesType.零售:
                    customerPrice = product.RetailPrice;
                    break;
                case SalesType.批发:
                    customerPrice = product.BatchPrice;
                    break;
                case SalesType.优惠价:
                    customerPrice = product.PreferentialPrice;
                    break;
                case SalesType.最低价:
                    customerPrice = product.LowestPrice;
                    break;
            }
            return customerPrice;
        }

        #region BarButtonItem Event

        private void SaveButtonItem_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            currSaleOrder.DeliveryDate = this.dtDeliveryDate.DateTime;
            currSaleOrder.TotalAmount = float.Parse(this.gvSaleOrder.Columns["Amount"].SummaryItem.SummaryValue.ToString());
            BalanceForm balanceForm = new BalanceForm(objectSpace, unitOfWork, currSaleOrder);
            if (balanceForm.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
            {
                XtraMessageBox.Show("保存成功", "提示", MessageBoxButtons.OK);
            }
        }

        private void NewButtonItem_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {

        }

        private void DeleteButtonItem_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {

        }

        private void CancelButtonItem_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {

        }

        private void PrintButtonItem_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {

        }

        private void CloseButtonItem_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            this.Close();
        }
        #endregion

        #region SearchResultGrid Event

        void gvSearchResult_Click(object sender, EventArgs e)
        {
            if (gvSearchResult.FocusedRowHandle >= 0)
            {
                int i = gvSearchResult.GetDataSourceRowIndex(gvSearchResult.FocusedRowHandle);
                Product currProduct = (Product)gvSearchResult.GetRow(i);
                //currSaleOrder.Customer = objectSpace.FindObject<Customer>(CriteriaOperator.Parse("ShortName = ?", this.txtCustomerName.Text));
                this.BindSaleHistory(currProduct.ProductCode);
                this.BindPurchase(currProduct.ProductCode);
                this.BindCustomOrder(currProduct.ProductCode, currSaleOrder.Customer);
                this.BindProductInfo(currProduct);
            }
        }

        private void BindSaleHistory(string productCode)
        {
            CriteriaOperator op = new BinaryOperator("Product.ProductCode", productCode, BinaryOperatorType.Equal);
            op = GroupOperator.Combine(GroupOperatorType.And, op,
                CriteriaOperator.Parse("SaleOrder.SoStatus=? or SaleOrder.SoStatus=? or SaleOrder.SoStatus=?", OrderStatusType.已开单, OrderStatusType.已确认, OrderStatusType.已审核));
            IList<SaleOrderItems> lstSaleOrderItems = objectSpace.GetObjects<SaleOrderItems>(op);
            this.SaleHistoryGridControl.DataSource = lstSaleOrderItems;
        }

        private void BindPurchase(string productCode)
        {
            CriteriaOperator op = new BinaryOperator("Product.ProductCode", productCode, BinaryOperatorType.Equal);
            op = GroupOperator.Combine(GroupOperatorType.And, op,
                CriteriaOperator.Parse("PurchasingOrder.POStatus=? or PurchasingOrder.POStatus=? or PurchasingOrder.POStatus=?", OrderStatusType.已开单, OrderStatusType.已确认, OrderStatusType.已审核));
            IList<PurchasingOrderItems> lstPurchasingOrderItems = objectSpace.GetObjects<PurchasingOrderItems>(op);
            this.PurchaseGridControl.DataSource = lstPurchasingOrderItems;
        }

        private void BindCustomOrder(string productCode, Customer currCustomer)
        {
            if (currCustomer != null)
            {
                CriteriaOperator op = new BinaryOperator("Product.ProductCode", productCode, BinaryOperatorType.Equal);
                op = GroupOperator.Combine(GroupOperatorType.And, op, CriteriaOperator.Parse("SaleOrder.Customer=?", currCustomer));
                op = GroupOperator.Combine(GroupOperatorType.And, op,
                    CriteriaOperator.Parse("SaleOrder.SoStatus=? or SaleOrder.SoStatus=? or SaleOrder.SoStatus=?", OrderStatusType.已开单, OrderStatusType.已确认, OrderStatusType.已审核));
                IList<SaleOrderItems> lstSaleOrderItems = objectSpace.GetObjects<SaleOrderItems>(op);
                this.SaleHistoryGridControl.DataSource = lstSaleOrderItems;
            }
        }

        private void BindProductInfo(Product currProduct)
        {
            this.txtProductDescription.Text = currProduct.ProductDescription;
        }

        void gvSearchResult_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (gvSearchResult.FocusedRowHandle >= 0)
                    ShowConfirmAddWin();
            }
        }

        void gvSearchResult_DoubleClick(object sender, EventArgs e)
        {
            if (gvSearchResult.FocusedRowHandle >= 0)
                ShowConfirmAddWin();
        }
        #endregion

    }
}